package org.zachary.imitation.raft.option;


import org.zachary.imitation.raft.NodeImpl;
import org.zachary.imitation.raft.PeerId;
import org.zachary.imitation.raft.core.Replicator;
import org.zachary.imitation.raft.core.ReplicatorType;
import org.zachary.imitation.raft.util.Copiable;

import java.util.concurrent.ScheduledExecutorService;


/**
 * {@link Replicator} 复制器对象所需要的配置参数
 */
public class ReplicatorOptions implements Copiable<ReplicatorOptions> {
	/** 当一个节点成为 Leader 后，经过这个时间之后，就要立刻向 Follower 发送心跳消息了 */
	private long dynamicHeartBeatTimeoutMs;
	/** 超时选举的时间 */
	private long electionTimeoutMs;
	private String groupId;
	/** Leader */
	private PeerId serverId;
	/** Follower */
	private PeerId peerId;
	/** Leader 对应的节点对象 */
	private NodeImpl node;
	/** Leader 当前所处的任期 */
	private long term;
	// private RaftClientService raftRpcService;
	// private Scheduler timerManager;
	/** 心跳、复制日志等所用到的基于 JDK 的定时任务 */
	private ScheduledExecutorService scheduledExecutorService;
	private ReplicatorType replicatorType;

	public ReplicatorOptions() {
		super();
	}

	public ReplicatorOptions(final ReplicatorType replicatorType, final int dynamicHeartBeatTimeoutMs,
							 final int electionTimeoutMs, final String groupId, final PeerId serverId,
							 final PeerId peerId, final NodeImpl node, final long term /*, final RaftClientService raftRpcService*/) {
		this.replicatorType = replicatorType;
		this.dynamicHeartBeatTimeoutMs = dynamicHeartBeatTimeoutMs;
		this.electionTimeoutMs = electionTimeoutMs;
		this.groupId = groupId;
		this.serverId = serverId;
		this.peerId = peerId;
		this.node = node;
		this.term = term;
		// this.raftRpcService = raftRpcService;
	}

	public final ReplicatorType getReplicatorType() {
		return this.replicatorType;
	}

	public void setReplicatorType(final ReplicatorType replicatorType) {
		this.replicatorType = replicatorType;
	}

//	public RaftClientService getRaftRpcService() {
//		return this.raftRpcService;
//	}
//
//	public void setRaftRpcService(final RaftClientService raftRpcService) {
//		this.raftRpcService = raftRpcService;
//	}

	@Override
	public ReplicatorOptions copy() {
		final ReplicatorOptions replicatorOptions = new ReplicatorOptions();
//		replicatorOptions.setDynamicHeartBeatTimeoutMs(this.dynamicHeartBeatTimeoutMs);
//		replicatorOptions.setReplicatorType(this.replicatorType);
//		replicatorOptions.setElectionTimeoutMs(this.electionTimeoutMs);
//		replicatorOptions.setGroupId(this.groupId);
//		replicatorOptions.setServerId(this.serverId);
//		replicatorOptions.setPeerId(this.peerId);
//		replicatorOptions.setNode(this.node);
//		replicatorOptions.setTerm(this.term);
//		replicatorOptions.setRaftRpcService(this.raftRpcService);
//		replicatorOptions.setTimerManager(this.timerManager);
		return replicatorOptions;
	}

	public PeerId getPeerId() {
		return this.peerId;
	}

	public void setPeerId(final PeerId peerId) {
		this.peerId = peerId;
	}

	public long getDynamicHeartBeatTimeoutMs() {
		return this.dynamicHeartBeatTimeoutMs;
	}

	public void setDynamicHeartBeatTimeoutMs(final long dynamicHeartBeatTimeoutMs) {
		this.dynamicHeartBeatTimeoutMs = dynamicHeartBeatTimeoutMs;
	}

	public long getElectionTimeoutMs() {
		return this.electionTimeoutMs;
	}

	public void setElectionTimeoutMs(final long electionTimeoutMs) {
		this.electionTimeoutMs = electionTimeoutMs;
	}

	public String getGroupId() {
		return this.groupId;
	}

	public void setGroupId(final String groupId) {
		this.groupId = groupId;
	}

	public PeerId getServerId() {
		return this.serverId;
	}

	public void setServerId(final PeerId serverId) {
		this.serverId = serverId;
	}


	public NodeImpl getNode() {
		return this.node;
	}

	public void setNode(final NodeImpl node) {
		this.node = node;
	}

	public long getTerm() {
		return this.term;
	}

	public void setTerm(final long term) {
		this.term = term;
	}

	public ScheduledExecutorService getScheduledExecutorService() {
		return scheduledExecutorService;
	}

	public void setScheduledExecutorService(ScheduledExecutorService scheduledExecutorService) {
		this.scheduledExecutorService = scheduledExecutorService;
	}
}
